package com.bruce.tool.message.aliyun.core;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.bruce.tool.common.exception.BaseRuntimeException;
import com.bruce.tool.common.exception.I18N;
import com.bruce.tool.common.util.LogUtils;
import com.bruce.tool.common.util.string.JsonUtils;
import com.bruce.tool.common.util.string.StringUtils;
import com.bruce.tool.common.util.valid.ValidUtils;
import com.bruce.tool.message.aliyun.constant.Constants;
import com.bruce.tool.message.aliyun.constant.MessageErrorCode;
import com.google.common.collect.Maps;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import javax.validation.constraints.NotNull;
import java.util.Map;

/**
 * 功能 :
 * 默认阿里云-云通信短信
 * @author : Bruce(刘正航) 18:15 2019-01-11
 */
@Slf4j
@NoArgsConstructor(staticName = "create")
public class Message {

    /**用户唯一标识**/
    @NotNull(message = "签名Key不能为空")
    private String appKey;
    /**用户秘钥**/
    @NotNull(message = "签名秘钥不能为空")
    private String appSecret;
    @NotNull(message = "手机号不能为空")
    private String phone;
    @NotNull(message = "短信模板编号不能为空")
    private String template;
    @NotNull(message = "短信签名不能为空")
    private String signature;

    private String region = "cn-hangzhou";
    private String endpoint = "cn-hangzhou";
    private String extend;
    /**短信模板内容参数**/
    private Map<String,Object> params = Maps.newHashMap();

    public Message auth(String appKey, String appSecret){
        this.appKey = appKey;
        this.appSecret = appSecret;
        return this;
    }

    public Message template(String template){
        this.template = template;
        return this;
    }

    public Message signature(String signature){
        this.signature = signature;
        return this;
    }

    public Message phone(String phone){
        this.phone = phone;
        return this;
    }

    public Message param(String key, String value){
        this.params.put(key,value);
        return this;
    }

    public Message params(Map<String,Object> params){
        this.params = params;
        return this;
    }

    public Message region(String region){
        this.region = region;
        return this;
    }

    public Message endpoint(String endpoint){
        this.endpoint = endpoint;
        return this;
    }

    public Message extend(String extend){
        this.extend = extend;
        return this;
    }

    /**发送消息**/
    public void send(){
        try {

            ValidUtils.valid(this);

            DefaultProfile.addEndpoint(endpoint, region, Constants.PRODUCT, Constants.DOMAIN);

            //初始化acsClient,暂不支持region化
            IClientProfile profile = DefaultProfile.getProfile(region, this.appKey, this.appSecret);

            IAcsClient acsClient = new DefaultAcsClient(profile);

            SendSmsRequest request = buildRequest();

            //hint 此处可能会抛出异常，注意catch
            SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);

            LogUtils.info(log,"云通信返回信息:{}",JsonUtils.objToStr(sendSmsResponse));

            if( !MessageErrorCode.SUCCESS.getCode().equalsIgnoreCase(sendSmsResponse.getCode()) ){
                throw new BaseRuntimeException(sendSmsResponse.getCode(), MessageErrorCode.getMessageByCode(sendSmsResponse.getCode(), I18N.ZH_CN));
            }
        } catch (BaseRuntimeException e) {
            throw new BaseRuntimeException(e.getCode(),e.getMessage(),e);
        } catch (Exception e) {
            throw new BaseRuntimeException(e);
        }
    }

    /**
     * 初始化请求对象
     */
    private SendSmsRequest buildRequest() {

        //组装请求对象-具体描述见控制台-文档部分内容
        SendSmsRequest request = new SendSmsRequest();
        //必填:待发送手机号
        request.setPhoneNumbers(this.phone);
        //必填:短信签名-可在短信控制台中找到
        request.setSignName(this.signature);
        //必填:短信模板-可在短信控制台中找到
        request.setTemplateCode(this.template);
        //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
        //"{\"name\":\"Tom\", \"code\":\"123\"}"
        request.setTemplateParam(JsonUtils.objToStr(this.params));

        //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
        if(StringUtils.isNotBlank(this.extend) ){
            request.setOutId(this.extend);
        }

        //可自助调整超时时间
        System.setProperty(Constants.SMS_CONNECT_TIMEOUT, "10000");
        System.setProperty(Constants.SMS_READ_TIMEOUT, "10000");

        return request;
    }
}
